int extract_tokens(const char *query)
{
        char *space = " ";
	char *obrace = "(";
	char *cbrace = ")";
	char *comma = ",";
	char *terminate = "\0";
	char *scolon = ";";
	char *equal = "=";
	int index=0, prev=0;
	int i=0;

#define CHAR_FOUND 1
#define PUNC_FOUND 2

	token_num=0;
	memset((void *) tokens,0, 100);

	for(i=0;i<MAX_QUERY_SIZE;i++)
	{
		if(strncmp(&query[i],terminate,1))	
		{
			if(!strncmp(&query[i],equal,1))
			{
				tokens[token_num][index++]='\0';
				token_num++;index=0;
				tokens[token_num][index++] = query[i];
				tokens[token_num][index++]='\0';
				token_num++;index=0;
				prev =  CHAR_FOUND;

			}else if(strncmp(&query[i],space,1)
				&& strncmp(&query[i],obrace,1) 
				&& strncmp(&query[i],comma,1) 
				&& strncmp(&query[i],cbrace,1)
				&& strncmp(&query[i],scolon,1) )
			{
				// Store the letter in the query and move index to store the next letter
				 tokens[token_num][index++] = query[i];
				 // Hack to check when punctuation marks hit continuously
				 prev = CHAR_FOUND;
		        }
			else if(';' == query[i])
			{
				tokens[token_num][index++]='\0';
				if(prev != PUNC_FOUND) {
					token_num++;
				}
				break;				
			}
			else
			{
				// Found a punctuation set the string in earlier token and goto next letter in the query
				 // Hack to check when punctuation marks hit continuously
				if(prev == CHAR_FOUND){
					tokens[token_num][index]='\0';
					token_num++;index=0;
				}
				prev = PUNC_FOUND;
			}
		}
	}

	for (i=0;i<token_num;i++)
	{
		DBGPRINTN(i);
		DBGPRINTS(tokens[i]);
	}

	DBGPRINTN(token_num);
	return(0);

}

#define DIFFTIME(x,y)	((y.tv_sec - x.tv_sec)*100000 + (y.tv_usec - x.tv_usec))
#define START	gettimeofday(&t_start, &tz1);
#define END	gettimeofday(&t_finish, &tz1);(timer? PRINT("\n\nCommand Time: %lu usecs \n" , DIFFTIME(t_start, t_finish)) :PRINT("\n"));PROMPT;

int create_table()
{
	int i=0, status=0;
	tableinfo tinfo;
	

	extract_tokens(lexer->YYText());
	// TABLE NAME is 3 token, skipping create TABLE T1 a1, a2
	strcpy(tinfo.table_name, tokens[2]);

	DBGPRINTN(token_num);
	for(i=3;i<token_num;i++)
	{
		strcpy(tinfo.attrib_names[i-3],tokens[i]);
	}
	tinfo.num_of_attribs =  (token_num - 3);
	DBGPRINTN(tinfo.num_of_attribs);

	tinfo.num_of_records = 0;
	tinfo.num_indexes = 0;

	DBGPRINTN(tinfo.num_of_records);
	DBGPRINTN(tinfo.num_indexes);

	status = db1->add_table(&tinfo);
	
	return(status);
}

int insert_values()
{
	int i=0;
	char tablename[TABLE_NAME_LENGTH];
	int attrib[MAX_NUM_ATTRIBS];

	
	extract_tokens(lexer->YYText());

	strcpy(tablename, tokens[2]);

	// Skip 4 tokens for (INSERT, INTO, TBLNAME, VALUES)
	for(i=4; i<token_num; i++)
		attrib[i-4] = atoi(tokens[i]);

	//for(i=0; i<token_num-4; i++) DBGPRINTF("%d\n",attrib[i]);

	DBGPRINTF("num values is %d\n", token_num-4);
	if(db1->insert_record(tablename, token_num-4, attrib))
	{
		FATAL("Either Table Name or Number of Values is wrong\n");
		return DATA_NOT_FOUND;
	}
	
	// get table name from token 1
	// check that no of values = table's num-attribues
	// use atoi() for converting ascii to integers
	// get values from 2 to end
	return(0);
}


/*** Select command: select *|[a1,a2,a3] from <Tablename> <... goes to query structure> ***/
/***			0   1, 2, 3	*/  
int select_call()
{
	int i=0, num_attribs=0;
	char tablename[TABLE_NAME_LENGTH];
	char attribs[MAX_NUM_ATTRIBS][ATTRIB_NAME_LENGTH];
	struct clause qry;

	extract_tokens(lexer->YYText());

	//i=0; skip the word select
	i=1;
	num_attribs=0;
	while(strcmp(tokens[i], "FROM") !=0 )
	{
		strcpy(attribs[num_attribs], tokens[i]);
		num_attribs++;
		DBGPRINTS((char *) (attribs+i-1));
		i++;
	}

	DBGPRINTN(num_attribs);

	strcpy(tablename, tokens[++i]); // Skip the token 'FROM'
	++i;
	if(i < token_num)
	{
		if(strcmp(tokens[i],"WHERE") == 0)
		{
			strcpy(qry.u.attrib,tokens[++i]);
			strcpy(qry.op,tokens[++i]);
			qry.val = atoi(tokens[++i]);
			status =db1->select_records((char *)tablename, num_attribs, (char *)attribs, &qry);
		}
		else
		{
			FATAL("Invalid clause %s",tokens[i]);
			return(DATA_NOT_FOUND);
		}

	} else	{
		DBGPRINTS(tablename);
		status = db1->select_records((char *)tablename, num_attribs, (char *)attribs, NULL); 
	}

	return(status);
}

/*** Index command: CREATE INDEX <IndexName> ON <TableName>(<AttribName>) ***/
/***			0    1        2       3      4          5         ***/  
int create_index(int flag)
{
	char iname[FILE_NAME_LENGTH];
	char tname[TABLE_NAME_LENGTH];
	char attrib[ATTRIB_NAME_LENGTH];

	extract_tokens(lexer->YYText());

	strcpy(iname, tokens[2]);
	strcpy(tname, tokens[4]);
	strcpy(attrib, tokens[5]);

	DBGPRINTS(tname);
	DBGPRINTS(iname);
	DBGPRINTS(attrib);

	if(db1->create_index(tname, iname, attrib, flag))
	{
		FATAL("Index %s cannot be created on %s\n", iname, attrib);
		return(DATA_NOT_FOUND);
	}
	
	return(0);
}

/*** Index command: PRINT INDEX <IndexName> ***/
/***			0    1        2     ***/  
void print_index()
{
	char iname[FILE_NAME_LENGTH];

	extract_tokens(lexer->YYText());

	strcpy(iname, tokens[2]);

	DBGPRINTS(iname);

	if(db1->print_index(iname))
	{
		FATAL("Index %s not found\n", iname);
	}
}

void print_hit_rate()
{
	db1->print_hit_rate();
}

void print_buffers()
{
	db1->print_buffers();
}

void print_buffer()
{
	//db1->print_buffers();
}


void print_catalog()
{
	db1->print();
}

void print_table()
{
	char tablename[TABLE_NAME_LENGTH];

	extract_tokens(lexer->YYText());

	//PRINT TABLE T1;
	strcpy(tablename, tokens[2]);
	db1->print(tablename);
}

void commit()
{

	db1->commit();

}

int quit()
{
	db1->commit();
	delete db1;
	return (0);
}
